package com.kly.user.task.v2.appflyers;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.net.NetUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Maps;
import com.kly.user.db.dao.UserAppflyersMappingDao;
import com.kly.user.db.dao.UserAppsflyerReportDao;
import com.kly.user.db.dao.UserAppsflyerReportDetailDao;
import com.kly.user.db.dao.UserDao;
import com.kly.user.db.entity.UserAppflyersMappingEntity;
import com.kly.user.db.entity.UserAppsflyerReportDetailEntity;
import com.kly.user.db.entity.UserAppsflyerReportEntity;
import com.kly.user.task.service.vo.AppflyerVO;
import com.kly.user.utils.HttpUtil;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.robert.vesta.util.IdUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * appFlyerPullApi任务
 */
@Service
public class AppflyerPullApiTask {

    private static Log logger = LogFactory.getLog(AppflyerPullApiTask.class);

    @NacosValue(value = "${task.job.executor.ip}", autoRefreshed = true)
    private String taskJobExecutor;
    @NacosValue(value = "${appsflyer.token}", autoRefreshed = true)
    private String token;
    private String localIP = NetUtil.getLocalhostStr();
    @Resource
    UserAppflyersMappingDao userAppflyersMappingDao;
    @Resource
    UserDao userDao;
    @Resource
    UserAppsflyerReportDetailDao appsflyerReportDetailDao;
    @Resource
    UserAppsflyerReportDao userAppsflyerReportDao;
    /**
     * 数据不完整标志
     */
    private final static Integer dataNComplete = 1;
    /**
     * pull api标志
     */
    private final static Integer fromPullApi = 2;
    /**
     * 拉取appflyers数据：每天凌晨4点执行
     */
    @Scheduled(cron = "0 0 4 * * ?")
    public void pullAppsflyerData() {
        logger.info("====AppflyerPullApiTask start");
        if (!taskJobExecutor.contains(localIP)) {
            logger.info("=============AppflyerPullApiTask, currentLocalAddress:{}, onlyExecuteTaskIn:{}", localIP, taskJobExecutor);
            return;
        }
        // 获取前1天appflyer数据
        final DateTime date = DateUtil.offsetDay(new Date(), -1);
        final DateTime startDate = DateUtil.beginOfDay(date);
        final DateTime endDate = DateUtil.endOfDay(date);
        // 调用pull api拉取最近两天数据
        final String csvDataFromAppsflyer = pullDataFromAppsflyer(startDate, endDate);
        if (StringUtils.isEmpty(csvDataFromAppsflyer)) {
            return;
        }

        final List<AppflyerVO> appflyerVos = csvToBeanByNameAnnotation(csvDataFromAppsflyer);
        if (CollectionUtils.isEmpty(appflyerVos)) {
            return;
        }

        final List<String> afids = appflyerVos.parallelStream().map(AppflyerVO::getAppsflyerId).collect(Collectors.toList());
        final Map<String, UserAppsflyerReportDetailEntity> appsflyerInfoDetailMap = getAppsflyerInfoDetail(afids);

        // 数据保存
        storeData(appflyerVos, appsflyerInfoDetailMap);

        // 处理未同步数据
        completeData(startDate, endDate);
    }

    private void storeData(List<AppflyerVO> appflyerVos, Map<String, UserAppsflyerReportDetailEntity> appsflyerInfoDetailMap) {
        for (AppflyerVO vo : appflyerVos) {
            try {
                String reportCode = IdUtils.genId() + "";
                UserAppsflyerReportEntity reportEntity = new UserAppsflyerReportEntity();
                reportEntity.setReportTime(DateUtil.format(new Date(), DatePattern.NORM_DATETIME_FORMATTER));
                reportEntity.setReportContent(JSONObject.toJSONString(vo));
                reportEntity.setReportCode(reportCode);
                reportEntity.setDataFrom(fromPullApi);
                userAppsflyerReportDao.insert(reportEntity);

                if (appsflyerInfoDetailMap.containsKey(vo.getAppsflyerId())) {
                    final UserAppsflyerReportDetailEntity existsRecord = appsflyerInfoDetailMap.get(vo.getAppsflyerId());
                    if (StringUtils.isEmpty(existsRecord.getAfChannel())) {
                        existsRecord.setReportCode(reportCode);
                        existsRecord.setAppVersion(vo.getAppVersion());
                        existsRecord.setAppName(vo.getAppName());
                        existsRecord.setWifi(vo.getWifi());
                        existsRecord.setMediaSource(vo.getMediaSource());
                        existsRecord.setCampaign(vo.getCampaign());
                        existsRecord.setAfChannel(vo.getChannel());
                        existsRecord.setLanguage(vo.getLanguage());
                        existsRecord.setAdvertisingId(vo.getAdvertisingId());
                        existsRecord.setOsVersion(vo.getOsVersion());
                        existsRecord.setPlatform(vo.getPlatform());
                        existsRecord.setState(vo.getState());
                        existsRecord.setCity(vo.getCity());
                        appsflyerReportDetailDao.updateByPrimaryKey(existsRecord);
                    }

                } else {
                    UserAppsflyerReportDetailEntity userAppsflyerReportDetailEntity = new UserAppsflyerReportDetailEntity();
                    userAppsflyerReportDetailEntity.setReportCode(reportCode);
                    userAppsflyerReportDetailEntity.setAppsflyerId(vo.getAppsflyerId());
                    userAppsflyerReportDetailEntity.setAppVersion(vo.getAppVersion());
                    userAppsflyerReportDetailEntity.setAppName(vo.getAppName());
                    userAppsflyerReportDetailEntity.setWifi(vo.getWifi());
                    userAppsflyerReportDetailEntity.setMediaSource(vo.getMediaSource());
                    userAppsflyerReportDetailEntity.setCampaign(vo.getCampaign());
                    userAppsflyerReportDetailEntity.setAfChannel(vo.getChannel());
                    userAppsflyerReportDetailEntity.setLanguage(vo.getLanguage());
                    userAppsflyerReportDetailEntity.setAdvertisingId(vo.getAdvertisingId());
                    userAppsflyerReportDetailEntity.setOsVersion(vo.getOsVersion());
                    userAppsflyerReportDetailEntity.setPlatform(vo.getPlatform());
                    userAppsflyerReportDetailEntity.setState(vo.getState());
                    userAppsflyerReportDetailEntity.setCity(vo.getCity());
                    appsflyerReportDetailDao.insert(userAppsflyerReportDetailEntity);
                }


            } catch (Exception e) {
                logger.error("addAppflyersInfoError", e);
            }
        }
    }


    public void completeData(DateTime startDate, DateTime endDate) {

        // 获取appflyer数据不完整记录
        final List<UserAppflyersMappingEntity> noneCompleteRecord = getUserAppflyersMappingEntities(startDate, endDate);
        if (CollectionUtils.isEmpty(noneCompleteRecord)) {
            return;
        }

        final List<String> afids = noneCompleteRecord.parallelStream().map(UserAppflyersMappingEntity::getAppflyersId).collect(Collectors.toList());
        final Map<String, UserAppsflyerReportDetailEntity> appsflyerInfoDetailMap = getAppsflyerInfoDetail(afids);

        for (UserAppflyersMappingEntity item : noneCompleteRecord) {
            if (appsflyerInfoDetailMap.containsKey(item.getAppflyersId())) {
                final UserAppsflyerReportDetailEntity detail = appsflyerInfoDetailMap.get(item.getAppflyersId());
                if (Objects.nonNull(detail) && StringUtils.isNotEmpty(detail.getAfChannel())) {
                    item.setChannel(detail.getAfChannel());
                    item.setCampaign(detail.getCampaign());
                    item.setDataCompleteFlag(dataNComplete);
                    userAppflyersMappingDao.updateByPrimaryKey(item);

                    // 更新channel
                    userDao.updateChannel(detail.getAppsflyerId(), detail.getAfChannel());
                }
            }
        }
    }

    private Map<String, UserAppsflyerReportDetailEntity> getAppsflyerInfoDetail(List<String> afids) {
        final List<UserAppsflyerReportDetailEntity> details = appsflyerReportDetailDao.listAppflyerReportDetail(afids);
        if (CollectionUtils.isEmpty(details)) {
            return Maps.newHashMap();
        }
        return details.parallelStream().collect(Collectors.toMap(UserAppsflyerReportDetailEntity::getAppsflyerId, Function.identity()));
    }


    /**
     * csv解析：根据bean标注的注解，解析csv文件，注解名为csv文件的列标题
     */
    private List<AppflyerVO> csvToBeanByNameAnnotation(String csvData) {
        final long startTime = System.currentTimeMillis();
        if (StringUtils.isEmpty(csvData)) {
            return null;
        }
        InputStream in = null;
        InputStreamReader reader = null;
        try {
            in = new ByteArrayInputStream(csvData.getBytes());
            reader = new InputStreamReader(in);
            // CsvBindByName注解的column属性为标题列名
            CsvToBean<AppflyerVO> csvToBean = new CsvToBeanBuilder<AppflyerVO>(reader).withType(AppflyerVO.class).build();

            final List<AppflyerVO> appflyerVOList = csvToBean.parse();
            logger.info("pullDataFromAppsflyer==costTime:{}, size:{}", System.currentTimeMillis() - startTime, appflyerVOList.size());
            return appflyerVOList;

        } catch (Exception e) {
            logger.error("csvToBeanByNameAnnotationError", e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                logger.error("closeInputStreamError", e);
            }
        }
        return null;
    }


    /**
     * 获取appflyer数据不完整记录
     */
    private List<UserAppflyersMappingEntity> getUserAppflyersMappingEntities(DateTime startDate, DateTime endDate) {
        return userAppflyersMappingDao.listDataNoneCompleteRecord(startDate, endDate);
    }

    public static void main(String[] args) throws Exception{

        String startDateStr = "2024-03-12";
        String endDateStr = "2024-03-12";

        String url = "https://hq1.appsflyer.com/api/raw-data/export/app/com.kly.meboo/installs_report/v5?from="+startDateStr+"&to="+endDateStr+"&timezone=America%2FLos_Angeles&maximum_rows=1000000&additional_fields=blocked_reason_rule,store_reinstall,impressions,contributor3_match_type,custom_dimension,conversion_type,gp_click_time,match_type,mediation_network,oaid,deeplink_url,blocked_reason,blocked_sub_reason,gp_broadcast_referrer,gp_install_begin,campaign_type,custom_data,rejected_reason,device_download_time,keyword_match_type,contributor1_match_type,contributor2_match_type,device_model,monetization_network,segment,is_lat,gp_referrer,blocked_reason_value,store_product_page,device_category,app_type,rejected_reason_value,ad_unit,keyword_id,placement,network_account_id,install_app_store,amazon_aid,att";

        final HashMap<String, String> header = Maps.newHashMap();
        header.put("accept", "text/csv");
        header.put("authorization", "Bearer eyJhbGciOiJBMjU2S1ciLCJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIiwiemlwIjoiREVGIn0.4g8iu0PIB6AH2duikBzCBtPkteXLA-9pGbWENNuHW1oKo7Y3lDVvJg.azQh4K2ZsFaa4-91.inHlVlAGwzD0DuJRhM0w3tjlPZTYMiQssUsAM0gAzdTzUImQmOP_euBg7j2Hpz8SSdFVD4AdPv5uZ-PNPpgUqkajZpPtNIMZqVhA2zAt-gG3n1zHOFFJ_V0paJndmg0ERqAtH-r7MKIJhQi5r2mC0O8cG8p2MDViXIHBkF58axRnsftARS8nieySS1dwrQ9rTkC5Oix3KCOjyZvbZN-WbIR7tqdZUqXQiU9pOUG3pkMP2oNveLyCsy4slPZ27Cp3yDowFrRkj3VEbRTKEl75eQpCe-Zee-biQdzYTM62d4AKj5qXNkNJcPPYrhfu0_oUqkPz3yZNyKI_kRK-894CmYjIyQ.c26KwnZwJINiun3NfZt-BQ");

        final String result = HttpUtil.getPage(url, null, header);

        System.out.println(result);



    }

    /**
     * 调用pull api拉取最近两天数据
     */
    private String pullDataFromAppsflyer(DateTime startDate, DateTime endDate) {
        final long startTime = System.currentTimeMillis();
        String startDateStr = DateUtil.format(startDate, DatePattern.NORM_DATE_FORMAT);
        String endDateStr = DateUtil.format(endDate, DatePattern.NORM_DATE_FORMAT);

        String url = "https://hq1.appsflyer.com/api/raw-data/export/app/com.kly.meboo/installs_report/v5?from="+startDateStr+"&to="+endDateStr+"&timezone=America%2FLos_Angeles&maximum_rows=1000000&additional_fields=blocked_reason_rule,store_reinstall,impressions,contributor3_match_type,custom_dimension,conversion_type,gp_click_time,match_type,mediation_network,oaid,deeplink_url,blocked_reason,blocked_sub_reason,gp_broadcast_referrer,gp_install_begin,campaign_type,custom_data,rejected_reason,device_download_time,keyword_match_type,contributor1_match_type,contributor2_match_type,device_model,monetization_network,segment,is_lat,gp_referrer,blocked_reason_value,store_product_page,device_category,app_type,rejected_reason_value,ad_unit,keyword_id,placement,network_account_id,install_app_store,amazon_aid,att";

        final HashMap<String, String> header = Maps.newHashMap();
        header.put("accept", "text/csv");
        header.put("authorization", "Bearer " + token);

        final String result = HttpUtil.getPage(url, null, header);
        logger.info("pullDataFromAppsflyer==costTime:{}", System.currentTimeMillis() - startTime);
        return result;
    }

}